<template>
  <div class="channel-edit">
    <van-cell title="我的频道" :border="false">
      <van-button
        :class="{ finish_btn: isEdit }"
        size="mini"
        round
        type="danger"
        plain
        @click="onClickEditOrFinishBtn"
      >
        &nbsp;&nbsp;{{ isEdit ? '完成' : '编辑' }}&nbsp;&nbsp;
      </van-button>
    </van-cell>
    <van-grid :gutter="10">
      <!-- 
        补充说明：
          1. 自定义组件指的是 所有的 非原生标签，包括第三方 UI 组件库的 组件 也是自定义组件，只不过，是别人定义的
          2. 在自定义组件身上绑定的所有事件，都属于组件的自定义事件，别看名字长得像原生事件，比如（@click、@keyup、@change），除非加了.native修饰符，才表示监听的是原生事件，比如（@click.native、@keyup.native、@change.native）
          3. 基于上述第2点，所以，不是所有自定义组件都能监听类似于（@click、@keyup、@change）的，能监听的前提条件是：该组件内部通过$emit('click||keyup||change') 触发了该自定义事件
      -->
      <van-grid-item
        class="channel-item"
        v-for="(v, i) of myChannels"
        :key="v.id"
        @click="changeActiveChannel(i)"
      >
        <template #text>
          <span class="text" :class="{ active: i === activeChannelIndex }">{{ v.name }}</span>
        </template>
        <template #icon>
          <!-- 如果索引是0，不显示关闭图标 -->
          <van-icon v-show="isEdit && i !== 0" name="close" @click.stop="removeMyChannel(i)" />
        </template>
      </van-grid-item>
    </van-grid>
    <van-cell title="频道推荐" :border="false"></van-cell>
    <van-grid class="recommend-grid" :gutter="10">
      <van-grid-item
        class="channel-item"
        v-for="v of recommendChannels"
        :key="v.id"
        :text="v.name"
        icon="plus"
        @click="addMyChannel(v)"
      />
    </van-grid>
  </div>
</template>

<script>
import { getAllChannels, setUserChannels } from '@/api/channel'
import { setItem } from '@/utils/storage'

export default {
  name: 'ChannelEdit',
  props: {
    activeChannelIndex: {
      type: Number,
      required: true,
    },
    myChannels: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      allChannels: [], // 所有频道列表
      isEdit: false, // 是否是编辑状态
    }
  },
  computed: {
    recommendChannels() {
      return this.allChannels.filter(v => {
        // v: 所有频道列表中，每次循环的频道对象
        // 如果 return true，就拿出来 放到 新数组中，如果 return false，就跳过，看下一个，直到最后一个，循环结束后，filter 函数 返回结果为 那个装所有拿出来元素的 新数组

        // 如何判断一个数组中包含某个元素呢？用 some

        // 数组的 some 函数，用来查找数组中是否有一个满足条件
        // 就看 我的频道列表中 是否存在 v.id
        // inside 为 true 就说明在我的频道列表中，反之 则不在
        const inside = this.myChannels.some(v2 => {
          // v2: 我的频道列表中，每次循环的频道对象
          // some 的回调 如果 return true，就说明找到了一个，会停止向后查找，some 函数 返回结果为 true，如果 return false，就跳过，看下一个，直到最后一个，如果所有都 return false，则 some 函数 返回结果为 false，表示没找到
          return v2.id === v.id
        })

        // if (inside) return false
        // return true

        return !inside // 返回不在里面的，和上面两行代码等价
      })
    },
  },
  methods: {
    onClickEditOrFinishBtn() {
      // 如果当前是编辑状态，就说明点的是完成按钮
      if (this.isEdit) {
        // 如果登录了（vuex中有token），调用后端接口
        if (this.$store.state.user.token) {
          // map方法的作用：做映射
          //   接收一个回调函数，该回调函数会被循环调用，返回值会作为映射出来的新数组的元素，当循环完后，map 函数会返回那个映射出来的新数组
          const channels = this.myChannels.map((v, i) => {
            return {
              id: v.id,
              seq: String(i + 1), // 索引i从0开始，但是后端要的seq从1开始
            }
          })

          // 发出请求之前，开启加载中转圈圈
          this.$toast.loading({
            message: '更新中...',
            duration: 0,
            forbidClick: true,
          })

          setUserChannels(channels)
            .then(() => {
              // 要先发请求，将我的频道数据保存后，再将编辑状态改过来
              this.isEdit = false
              this.$toast.success('更新成功') // 请求成功后，给出成功提示
            })
            .catch(err => {
              this.$toast.fail(err.response.data.message) // 获取后端返回的错误消息，提示出来
            })
        }
        // 没登录，存本地
        else {
          setItem('user_channels', this.myChannels)
          this.isEdit = false // 将编辑状态改过来
          this.$toast.success('更新成功') // 请求成功后，给出成功提示
        }
      }
      // 否则，说明点的是编辑按钮
      else {
        this.isEdit = true
      }
    },
    addMyChannel(channel) {
      if (!this.isEdit) return
      this.$emit('addMyChannel', channel)
    },
    removeMyChannel(i) {
      if (i === 0) return // 如果删的第一个，不能删
      this.$emit('removeMyChannel', i)
    },
    changeActiveChannel(i) {
      // 如果是编辑状态，就去做删除
      if (this.isEdit) {
        this.removeMyChannel(i)
      }
      // 不是编辑状态，再去做切换频道
      else {
        this.$emit('update:activeChannelIndex', i)
      }
    },
  },
  created() {
    console.log('ChannelEdit created 钩子执行了')

    this.$toast.loading({
      message: '列表加载中...',
      forbidClick: true,
      duration: 0,
    })

    getAllChannels()
      .then(res => {
        this.allChannels = res.data.data.channels
      })
      .finally(() => {
        this.$toast.clear()
      })
  },
}
</script>

<style lang="less" scoped>
.channel-edit {
  .finish_btn {
    background-color: #ee0a24;
    color: white;
  }

  /deep/ .van-icon-close {
    position: absolute;
    right: -10px;
    top: -10px;
    font-size: 36px;
    color: #ccc;
  }

  /deep/ .recommend-grid {
    height: 100px;
    .van-grid-item__content {
      flex-direction: row;

      color: #222;
      .van-icon {
        font-size: 24px;
      }

      .van-grid-item__text {
        font-size: 24px;
        margin-top: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }
    }
  }

  .channel-item {
    height: 100px;
    /deep/ .van-grid-item__content {
      background-color: #f5f5f6;

      .van-grid-item__icon-wrapper {
        position: unset;
      }

      .text {
        color: #222;
        font-size: 24px;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        &.active {
          color: red;
        }
      }
    }
  }
}
</style>
